const fs = require('fs');
const path = require('path');
const { PDFDocument } = require('pdf-lib');

class ImageToPdfConverter {
  constructor(config) {
    this.config = config;
    this.ensureOutputDir();
    // 创建未铺满宽度的目录 - 仅在适应宽度模式下
    const scaleMode = this.config.scaleMode || 'fitWidth';
    if (scaleMode === 'fitWidth') {
      this.ensureNotFullWidthDir(); // 确保未铺满宽度目录存在
    }
  }

  ensureOutputDir() {
    if (!fs.existsSync(this.config.outputDir)) {
      fs.mkdirSync(this.config.outputDir, { recursive: true });
      console.log(`创建输出目录: ${this.config.outputDir}`);
    }
  }

  // 确保未铺满宽度的图片目录存在
  ensureNotFullWidthDir() {
    if (!fs.existsSync(this.config.notFullWidthDir)) {
      fs.mkdirSync(this.config.notFullWidthDir, { recursive: true });
      console.log(`创建未铺满宽度图片目录: ${this.config.notFullWidthDir}`);
    }
  }

  // 清空未铺满宽度的图片目录
  clearNotFullWidthDir() {
    if (!fs.existsSync(this.config.notFullWidthDir)) {
      return;
    }

    try {
      const files = fs.readdirSync(this.config.notFullWidthDir);
      let deletedCount = 0;

      for (const file of files) {
        const filePath = path.join(this.config.notFullWidthDir, file);
        const stat = fs.statSync(filePath);

        if (stat.isFile()) {
          fs.unlinkSync(filePath);
          deletedCount++;
        }
      }

      if (deletedCount > 0) {
        console.log(`已清空未铺满宽度图片目录，删除了 ${deletedCount} 个文件`);
      }
    } catch (error) {
      console.error(`清空未铺满宽度图片目录失败: ${error.message}`);
    }
  }

  // 复制文件到目标目录
  copyFileToDir(sourcePath, destDir, filename) {
    const destPath = path.join(destDir, filename);
    try {
      fs.copyFileSync(sourcePath, destPath);
      return true;
    } catch (error) {
      console.error(`复制文件失败 ${filename}: ${error.message}`);
      return false;
    }
  }

  // 使用pdf-lib库转换图片为PDF
  async convertWithPdfLib(imageFiles, outputPdfPath) {
    console.log(`使用pdf-lib转换 ${imageFiles.length} 张图片...`);

    const pdfDoc = await PDFDocument.create();
    let successCount = 0;
    let failCount = 0;
    const failedFiles = []; // 记录失败的文件
    const notFullWidthFiles = []; // 记录宽度没有铺满PDF的文件
    const imagesWithRenderInfo = []; // 记录所有图片的渲染信息

    for (let i = 0; i < imageFiles.length; i++) {
      const imageFile = imageFiles[i];
      const imagePath = path.join(this.config.imageDir, imageFile);

      try {
        console.log(`[${i + 1}/${imageFiles.length}] 处理: ${imageFile}`);

        const imageBytes = fs.readFileSync(imagePath);
        const ext = path.extname(imageFile).toLowerCase();

        let image;
        if (ext === '.jpg' || ext === '.jpeg') {
          image = await pdfDoc.embedJpg(imageBytes);
        } else if (ext === '.png') {
          image = await pdfDoc.embedPng(imageBytes);
        } else {
          console.log(`  ⚠️ 跳过不支持的格式: ${ext}`);
          failCount++;
          continue;
        }

        // 获取图片尺寸
        const imgWidth = image.width;
        const imgHeight = image.height;

        // 始终使用A4尺寸创建页面，确保所有页面尺寸一致
        const page = pdfDoc.addPage([this.config.a4Width, this.config.a4Height]);
        const { width: pageWidth, height: pageHeight } = page.getSize();

        // 计算缩放比例 - 根据配置的缩放模式
        let drawWidth, drawHeight, x, y;
        let isFullWidth = true; // 标记是否铺满宽度
        
        const scaleMode = this.config.scaleMode || 'fitWidth';
        
        if (scaleMode === 'fitHeight') {
          // 适应高度：铺满高度，宽度按比例缩放
          drawHeight = pageHeight;
          drawWidth = (imgWidth / imgHeight) * pageHeight;
          
          // 如果宽度超过页面宽度，则限制宽度并调整高度
          if (drawWidth > pageWidth) {
            drawWidth = pageWidth;
            drawHeight = (imgHeight / imgWidth) * pageWidth;
            // 垂直居中
            y = (pageHeight - drawHeight) / 2;
            isFullWidth = true; // 宽度铺满
          } else {
            // 高度铺满
            y = 0;
            isFullWidth = false; // 宽度没有铺满
            // 仅在适应宽度模式下收集未铺满宽度的文件
            if (scaleMode === 'fitWidth') {
              notFullWidthFiles.push({ filename: imageFile, width: drawWidth, pageWidth: pageWidth, path: imagePath });
            }
          }
          
          // 水平居中
          x = (pageWidth - drawWidth) / 2;
          
        } else if (scaleMode === 'fitBoth') {
          // 适应页面：保持图片比例，确保整个图片都能显示在页面内
          const widthRatio = pageWidth / imgWidth;
          const heightRatio = pageHeight / imgHeight;
          const scale = Math.min(widthRatio, heightRatio);
          
          drawWidth = imgWidth * scale;
          drawHeight = imgHeight * scale;
          
          // 水平居中
          x = (pageWidth - drawWidth) / 2;
          // 垂直居中
          y = (pageHeight - drawHeight) / 2;
          
          isFullWidth = drawWidth >= pageWidth;
          // 仅在适应宽度模式下收集未铺满宽度的文件
          if (!isFullWidth && scaleMode === 'fitWidth') {
            notFullWidthFiles.push({ filename: imageFile, width: drawWidth, pageWidth: pageWidth, path: imagePath });
          }
          
        } else {
          // 默认适应宽度：铺满宽度，高度按比例缩放
          drawWidth = pageWidth;
          drawHeight = (imgHeight / imgWidth) * pageWidth;
          
          // 如果高度超过页面高度，则限制高度并调整宽度
          if (drawHeight > pageHeight) {
            drawHeight = pageHeight;
            drawWidth = (imgWidth / imgHeight) * pageHeight;
            // 水平居中
            x = (pageWidth - drawWidth) / 2;
            isFullWidth = false; // 宽度没有铺满
            notFullWidthFiles.push({ filename: imageFile, width: drawWidth, pageWidth: pageWidth, path: imagePath });
          } else {
            // 宽度铺满
            x = 0;
          }
          
          // 垂直居中
          y = (pageHeight - drawHeight) / 2;
        }

        page.drawImage(image, {
          x: x,
          y: y,
          width: drawWidth,
          height: drawHeight,
        });

        // 保存图片渲染信息（包括PDF中显示的高度）
        imagesWithRenderInfo.push({
          filename: imageFile,
          originalWidth: imgWidth,
          originalHeight: imgHeight,
          renderWidth: drawWidth,
          renderHeight: drawHeight,
          path: imagePath
        });

        successCount++;
        console.log(`  ✅ 成功添加到PDF${!isFullWidth ? ' (宽度未铺满)' : ''}`);

      } catch (error) {
        console.error(`  ❌ 处理失败: ${error.message}`);
        failCount++;
        failedFiles.push(imageFile);
      }
    }

    // 保存PDF
    const pdfBytes = await pdfDoc.save();
    fs.writeFileSync(outputPdfPath, pdfBytes);

    console.log(`
✅ PDF生成成功: ${outputPdfPath}`);
    console.log(`   成功: ${successCount} 张, 失败: ${failCount} 张`);

    if (failedFiles.length > 0) {
      console.log(`   失败的文件: ${failedFiles.join(', ')}`);
    }

    if (notFullWidthFiles.length > 0) {
      console.log(`
📋 宽度未铺满PDF的文件 (共${notFullWidthFiles.length}个):`);
      notFullWidthFiles.forEach(file => {
        console.log(`   - ${file.filename} (绘制宽度: ${file.width.toFixed(2)}, 页面宽度: ${file.pageWidth})`);
      });
    }

    return {
      outputPdfPath,
      notFullWidthFiles,
      imagesWithRenderInfo // 返回所有图片的渲染信息
    };
  }

  getSortedImageFiles() {
    return new Promise((resolve, reject) => {
      fs.readdir(this.config.imageDir, (err, files) => {
        if (err) {
          reject(new Error(`无法读取图片目录: ${err.message}`));
          return;
        }

        const imageFiles = files
          .filter(file => {
            const ext = path.extname(file).toLowerCase();
            return this.config.supportedFormats.includes(ext);
          })
          .sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));

        console.log(`找到 ${imageFiles.length} 个图片文件`);
        resolve(imageFiles);
      });
    });
  }

  // 主转换方法
  async convertImagesToPdf(imageFiles, outputPdfPath) {
    return await this.convertWithPdfLib(imageFiles, outputPdfPath);
  }

  getFileNameWithoutExt(filename) {
    return path.parse(filename).name;
  }

  fileExists(filePath) {
    return fs.existsSync(filePath);
  }

  async convert(mainWindow = null) {
    try {
      // 清空未铺满宽度的图片目录
      this.clearNotFullWidthDir();

      const imageFiles = await this.getSortedImageFiles();
      if (imageFiles.length === 0) {
        throw new Error('未找到支持的图片文件');
      }

      // 初始化第一个图片渲染高度变量
      let firstImageRenderHeight = null;
      // 添加容差范围，允许1%的高度差异
      const heightTolerance = 0.01;

      // 记录需要复制到notFullWidthDir的图片
      const imagesToCopy = [];

      // 分批处理
      const batches = [];
      for (let i = 0; i < imageFiles.length; i += this.config.maxPagesPerPdf) {
        batches.push(imageFiles.slice(i, i + this.config.maxPagesPerPdf));
      }

      let successfulBatches = 0;
      const allNotFullWidthFiles = []; // 收集所有批次中宽度未铺满的文件

      const outputPaths = [];
      
      for (let i = 0; i < batches.length; i++) {
        const batch = batches[i];
        
        // 发送进度更新
        if (mainWindow) {
          const progress = Math.round(((i + 1) / batches.length) * 100);
          mainWindow.webContents.send('progress-update', {
            type: 'create-pdf',
            progress
          });
        }

        let outputFilename;
        if (this.config.customPdfName) {
          // 使用自定义PDF名称
          if (batches.length === 1) {
            outputFilename = `${this.config.customPdfName}.pdf`;
          } else {
            // 多批次时添加序号后缀
            outputFilename = `${this.config.customPdfName}-${(i + 1).toString().padStart(4, '0')}.pdf`;
          }
        } else if (batches.length === 1) {
          // 如果只有一个批次，直接使用第一个图片的文件名
          const firstImageName = this.getFileNameWithoutExt(batch[0]);
          outputFilename = `${firstImageName}.pdf`;
        } else {
          // 如果有多个批次，添加序号后缀（四位数字格式：0001, 0002, ...）
          const firstImageName = this.getFileNameWithoutExt(batches[0][0]);
          outputFilename = `${firstImageName}-${(i + 1).toString().padStart(4, '0')}.pdf`;
        }

        const outputPdfPath = path.join(this.config.outputDir, outputFilename);
        outputPaths.push(outputPdfPath);

        if (this.fileExists(outputPdfPath) && !this.config.forceRegenerate) {
          continue;
        }

        try {
          const result = await this.convertImagesToPdf(batch, outputPdfPath);
          successfulBatches++;

          // 收集宽度未铺满的文件
          if (result.notFullWidthFiles && result.notFullWidthFiles.length > 0) {
            allNotFullWidthFiles.push(...result.notFullWidthFiles);
            // 添加到需要复制的列表
            result.notFullWidthFiles.forEach(file => {
              imagesToCopy.push(file);
            });
          }

          // 处理图片渲染高度信息
          if (result.imagesWithRenderInfo) {
            // 第一次处理时，记录第一个成功处理图片的渲染高度
            if (firstImageRenderHeight === null && result.imagesWithRenderInfo.length > 0) {
              firstImageRenderHeight = result.imagesWithRenderInfo[0].renderHeight;
            }

            // 收集渲染高度小于第一个图片渲染高度一定阈值的文件
            if (firstImageRenderHeight !== null) {
              const smallerHeightImages = result.imagesWithRenderInfo.filter(
                file => file.renderHeight < firstImageRenderHeight * (1 - heightTolerance)
              );

              if (smallerHeightImages.length > 0) {
                // 确保不重复添加
                smallerHeightImages.forEach(file => {
                  if (!imagesToCopy.some(item => item.filename === file.filename)) {
                    imagesToCopy.push(file);
                  }
                });
              }
            }
          }
        } catch (error) {
          throw new Error(`批次 ${i + 1} 失败: ${error.message}`);
        }
      }

      // 仅在适应宽度模式下处理未铺满宽度的文件
      const scaleMode = this.config.scaleMode || 'fitWidth';
      if (scaleMode === 'fitWidth') {
        // 输出所有宽度未铺满的文件汇总
        if (allNotFullWidthFiles.length > 0) {
          // 将未铺满宽度的文件信息保存到文件
          const reportPath = path.join(this.config.outputDir, '未铺满宽度的文件报告.txt');
          const reportContent = `宽度未铺满PDF的文件汇总 (共${allNotFullWidthFiles.length}个):\n\n` +
            allNotFullWidthFiles.map(file =>
              `${file.filename} (绘制宽度: ${file.width.toFixed(2)}, 页面宽度: ${file.pageWidth})`
            ).join('\n');
          fs.writeFileSync(reportPath, reportContent, 'utf-8');
        }

        // 复制需要的文件到指定目录
        if (imagesToCopy.length > 0) {
          let copiedCount = 0;
          for (const file of imagesToCopy) {
            if (this.copyFileToDir(file.path, this.config.notFullWidthDir, file.filename)) {
              copiedCount++;
            }
          }
        }
      }

      // 发送完成消息
      if (mainWindow) {
        mainWindow.webContents.send('progress-update', {
          type: 'create-pdf',
          progress: 100
        });
      }

      return { success: true, batches: batches.length, successful: successfulBatches, outputPaths: outputPaths };

    } catch (error) {
      // 发送错误消息
      if (mainWindow) {
        mainWindow.webContents.send('progress-update', {
          type: 'create-pdf',
          progress: 0,
          error: error.message
        });
      }
      throw error;
    }
  }
}

// 导出类
module.exports = ImageToPdfConverter;


